#include <cppconn/prepared_statement.h>
#include <cppconn/resultset.h>

#include <cstdio>
#include <iostream>
#include <memory>
#include <string>

#include "Connection.h"

int main() {
    try {
        Connection conn("localhost", 3306, "root", "1234567", "chat");
        // 初始化表
        conn.update("drop table if exists user");
        conn.update(
            "create table user(id int primary key auto_increment, name "
            "varchar(50) "
            "not null, age int not null, sex enum('male','female') not null)");

        // 插入操作
        char sql_insert[1024] = {0};
        sprintf(sql_insert,
                "insert into user(name,age,sex) values ('%s',%d,'%s')", "eric",
                25, "male");
        conn.update(sql_insert);

        // 使用prepareStatement操作
        std::unique_ptr<sql::PreparedStatement> pstmt =
            conn.pstmt("insert into user(name,age,sex) values(?, ?, ?)");
        for (int i = 1; i <= 10; ++i) {
            pstmt->setString(1, "name" + std::to_string(i));
            pstmt->setInt(2, i * i);
            pstmt->setString(3, "male");
            pstmt->executeUpdate();
        }

        // 删除操作
        conn.update("delete from user where age=1");

        // 修改操作
        conn.update("update user set name='eva' where age=4");

        // 查询操作
        char sql_select[1024] = {0};
        sprintf(sql_select, "select * from user");
        std::shared_ptr<sql::ResultSet> res(conn.query(sql_select));
        while (res->next()) {
            std::cout << res->getInt(1) << "\t" << res->getString(2) << "\t"
                      << res->getInt(3) << "\t" << res->getString(4)
                      << std::endl;
        }
    } catch (sql::SQLException& e) {
        std::cout << "# ERR: SQLException in " << __FILE__;
        std::cout << "(" << __FUNCTION__ << ") on line " << __LINE__
                  << std::endl;
        std::cout << "# ERR: " << e.what();
        std::cout << " (MySQL error code: " << e.getErrorCode();
        std::cout << ", SQLState: " << e.getSQLState() << " )" << std::endl;
    }

    return 0;
}
